﻿using System;
using System.Collections.Generic;

namespace Core.StateSystem
{
    public class StateMachine<T>
    {
        private class State
        {
            public readonly T label;
            public readonly Action onStart;
            public readonly Func<T> onUpdate;
            public readonly Action onStop;

            public State(T label, Action onStart, Func<T> onUpdate, Action onStop)
            {
                this.label = label;
                this.onStart = onStart;
                this.onUpdate = onUpdate;
                this.onStop = onStop;
            }
        }

        /// <summary>
        /// 状态集合
        /// </summary>
        private readonly Dictionary<T, State> mStateDictionary;

        private State mCurrentState;

        /// <summary>
        /// 上一个状态
        /// </summary>
        private State mPreState;

        /// <summary>
        /// 进入的状态名称
        /// </summary>
        private T mEnterState;

        /// <summary>
        /// 当前状态的label
        /// </summary>
        public T CurrentState
        {
            get { return mCurrentState.label; }
            set { ChangeState(value); }
        }

        /// <summary>
        /// 返回上一状态label
        /// </summary>
        public T PreState => mPreState.label;

        public bool IsRunning
        {
            get { return CurrentState != null; }
        }

        public StateMachine()
        {
            mStateDictionary = new Dictionary<T, State>();
        }

        public void OnStart()
        {
            if (mStateDictionary.Count == 0)
            {
                return;
            }

            mCurrentState = mStateDictionary[mEnterState];
            if (mCurrentState != null && mCurrentState.onStart != null)
            {
                mCurrentState.onStart();
            }
        }

        public void OnUpdate()
        {
            if (mCurrentState != null && mCurrentState.onUpdate != null)
            {
                mCurrentState.onUpdate();
            }
        }

        public void OnStop()
        {
            if (mCurrentState != null && mCurrentState.onStop != null)
            {
                mCurrentState.onStop();
            }
        }

        /// <summary>
        /// 添加状态
        /// </summary>
        /// <param name="label">状态</param>
        /// <param name="onStart">在状态开始时调用</param>
        /// <param name="onUpdate">在状态期间持续调用</param>
        /// <param name="onStop">在状态结束时调用</param>
        public void AddState(T label, Action onStart, Func<T> onUpdate, Action onStop)
        {
            State state = new State(label, onStart, onUpdate, onStop);
            mStateDictionary[label] = state;
            if (mCurrentState == null) //第一个添加的状态为初始状态
            {
                mCurrentState = state;
                mEnterState = mCurrentState.label;
            }
        }


        /// <summary>
        /// 切换状态
        /// </summary>
        /// <param name="newLabel"></param>
        public void ChangeState(T newLabel)
        {
            if (mCurrentState != null && mCurrentState.onStop != null)
            {
                mCurrentState.onStop();
            }

            mPreState = mCurrentState;
            mCurrentState = mStateDictionary[newLabel];

            if (mCurrentState != null && mCurrentState.onStart != null)
            {
                mCurrentState.onStart();
            }
        }
    }
}